/**
 * =====================================================================================
 *
 *      @file:  cache_vector.c
 *
 *    	@brief:  手工实现的C语言vector类，类似于STL std::vecotr，此处是具体实现
 *
 *      @version:  1.0
 *      Created:  2010年04月08日 15时55分10秒
 *      Revision:  none
 *      Compiler:  gcc -Wall -Wextra vector.c
 *
 *      @author:  easyeagel (LiuGuangBao), easyeagel@gmx.com
 *      Company:  简单C++ - www.easycpp.org
 *
 * =====================================================================================
 */

#include<stdlib.h>
#include<assert.h>
#include<string.h>

#define M_vector_implement_file
#include"cache_vector.hpp"

vector_t* vct_create(size_t s,  size_t c)
{
	vector_t* ret=(vector_t*)malloc(sizeof(*ret));
	assert(ret);

	size_t n=s*c;
	void* list=malloc(n);
	assert(list);

	memset(ret, 0, sizeof(*ret));
	memset(list, 0, n);

	ret->step=s;
	ret->capacity=c;
	ret->vector=list;

	return ret;
}

void vct_free(vector_t* vct)
{
	size_t i;
	for(i=0; i < vct->index; ++i)
	{
		char* p=(char*)vct->vector;
		vct->destroy(p);
		p += vct->step;
	}

	free(vct->vector);
	free(vct);
}

vector_t* vct_recapacity(vector_t* vct, size_t c)
{
	if(c<=vct->capacity)
	{
		return vct;
	}

	void* rebuf=realloc(vct->vector, vct->step*c);
	assert(rebuf);

	vct->capacity=c;

	return vct;
}

void vct_pushback(vector_t* vct, void* d)
{
	if(vct->capacity <= vct->index)
	{
		vct_recapacity(vct, 2*vct->capacity);
	}

	char* p= (char*)vct->vector + vct->index*vct->step;
	vct->copy(p, d);

	vct->index += 1;
}

void* vct_find(vector_t* vct, void* d)
{
	size_t i=0;
	size_t n=vct->index;
	size_t step=vct->step;
	char* p=(char*)vct->vector;

	compare_fun_t compare=vct->compare;
	while(i<n)
	{
		if(0==compare(d, p))
		{
			return p;
		}

		p += step;
		i += 1;
	}

	return NULL;

}

void* vct_index(vector_t* vct, size_t idx)
{
	return (vct->index < idx) ? NULL : (char*)vct->vector + idx*vct->step;
}

void vct_qsort(vector_t* vct)
{
	qsort(vct->vector, vct->index, vct->step, vct->compare);
}

void* vct_bsearch(vector_t* vct, void*d)
{
	return bsearch(d, vct->vector, vct->index, vct->step, vct->compare);
}

void vct_fun_compare(vector_t* vct, compare_fun_t compare)
{
	vct->compare=compare;
}

void vct_fun_copy(vector_t* vct,  copy_fun_t copy)
{
	vct->copy=copy;
}

void vct_fun_free(vector_t* vct,  destroy_fun_t destroy)
{
	vct->destroy=destroy;
}

#undef M_vector_implement_file

